#include "gd32f30x.h" 
#include "MyUSART.h"
#include "string.h"
#include "FreeRTOS.h"
#include "task.h"
#include "stdio.h"
#include "event_groups.h"
#include "BMP280.h"
#include "Connect_ONENET.h"
#include "ui.h"
extern MYTime time;
extern EventGroupHandle_t WIFI_connected_Handle;
extern TaskHandle_t espsend_Handle;
extern EventGroupHandle_t TimeRefresh_Handle;
#define ESP8266_WIFI_INFO	   "AT+CWJAP=\"xiaoyi\",\"18770371787\"\r\n"
//#define ESP8266_TCP_INFO	   "AT+CIPSTART=\"TCP\",\"192.168.202.33\",8080\r\n"
#define ESP8266_TCP_INFO	   "AT+CIPSTART=\"TCP\",\"mqtts.heclouds.com\",1883\r\n"
// #define esp_tim				   "AT+CIPSNTPCFG=1,8,\"ntp.aliyun.com\"\r\n"
#define esp_tim				   "AT+CIPSNTPCFG=1,8,\"pool.ntp.org\"\r\n"
uint8_t test_hour;
uint8_t test_min;
uint8_t text_sec;
uint16_t test_year;
//mqtt的连接报文
const uint8_t mqtt_Connect_pack[] = {
    0x10, 0x9A, 0x01, 0x00, 0x04, 0x4D, 0x51, 0x54, 0x54, 0x04, 
    0xC2, 0x00, 0x5A, 0x00, 0x06, 0x78, 0x69, 0x61, 0x6F, 0x79, 
    0x69, 0x00, 0x0A, 0x4C, 0x36, 0x37, 0x33, 0x34, 0x6E, 0x62, 
    0x76, 0x7A, 0x6F, 0x00, 0x7A, 0x76, 0x65, 0x72, 0x73, 0x69, 
    0x6F, 0x6E, 0x3D, 0x32, 0x30, 0x31, 0x38, 0x2D, 0x31, 0x30, 
    0x2D, 0x33, 0x31, 0x26, 0x72, 0x65, 0x73, 0x3D, 0x70, 0x72, 
    0x6F, 0x64, 0x75, 0x63, 0x74, 0x73, 0x25, 0x32, 0x46, 0x4C, 
    0x36, 0x37, 0x33, 0x34, 0x6E, 0x62, 0x76, 0x7A, 0x6F, 0x25, 
    0x32, 0x46, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x25, 
    0x32, 0x46, 0x78, 0x69, 0x61, 0x6F, 0x79, 0x69, 0x26, 0x65, 
    0x74, 0x3D, 0x31, 0x37, 0x39, 0x34, 0x39, 0x31, 0x34, 0x33, 
    0x31, 0x30, 0x26, 0x6D, 0x65, 0x74, 0x68, 0x6F, 0x64, 0x3D, 
    0x6D, 0x64, 0x35, 0x26, 0x73, 0x69, 0x67, 0x6E, 0x3D, 0x4D, 
    0x38, 0x51, 0x79, 0x34, 0x53, 0x6B, 0x45, 0x42, 0x4C, 0x65, 
    0x77, 0x76, 0x53, 0x71, 0x38, 0x32, 0x76, 0x66, 0x41, 0x47, 
    0x41, 0x25, 0x33, 0x44, 0x25, 0x33, 0x44
};
extern EventGroupHandle_t ESP_EventGroup_Handle;
extern uint8_t cal_value;
uint8_t esp_buf[512];
uint16_t rxxcnt;
uint8_t flag = 0x00;
char* ret_time = NULL;
uint8_t check_connect_ack(void)
{
	//发送报文如果登录成果则会返回 20 02 00 00
	for(uint8_t i = 0; i < rxxcnt - 3; i++)
	{
		if(esp_buf[i] == 0x20 && esp_buf[i + 1] == 0x02 && esp_buf[i + 2] == 0x00 &&esp_buf[i + 3] == 0x00)
		{
			return 1;
		}
	}
	return 0;
}
void espcmd_init(char *cmd, char *rrret, uint8_t flagg)
{
	SendData(cmd,strlen(cmd));
	vTaskDelay(800);
	char* ret = strstr((char*)esp_buf, rrret);//查看接收缓冲区是否收到了来自esp32对应的内容
	(ret != NULL) ? (flag &= (~flagg)) : (flag |= flagg);//如果接收到了对应的内容，就不做如何置位，否则将对应位置一
	memset(esp_buf, 0, 512);//清空接收缓冲区
	rxxcnt = 0;//接收计数器清零
	ret = NULL;	
}
void espcmd_time_get(char *cmd, char *rrret,uint8_t flagg)
{
	SendData(cmd,strlen(cmd));
	vTaskDelay(800);
	ret_time = strstr((char*)esp_buf, rrret);//查看接收缓冲区是否收到了来自esp32对应的内容
	(ret_time != NULL) ? (flag &= (~flagg)) : (flag |= flagg);//如果接收到了对应的内容，就不做如何置位，否则将对应位置一
	char *pos = strstr((char*)esp_buf, "+CIPSNTPTIME:");
	if(pos != NULL)
	{
		uint8_t re_num = sscanf(pos, "+CIPSNTPTIME:%s %s %hhu %hhu:%hhu:%hhu %hu", time.weekday, time.month, &time.month_day, &time.hour, &time.min, &time.sec, &time.year);
		(re_num == 7) ? (flag &= (~flagg)) : (flag |= flagg);
	}


	rxxcnt = 0;//接收计数器清零
	ret_time = NULL;
	memset(esp_buf, 0, 512);//清空接收缓冲区	
}
void mqtt_espcmd_init(char *cmd,uint8_t len, uint8_t flagg)
{
	char SendBUf[128];
	sprintf(SendBUf, "AT+CIPSEND=%d\r\n", len);
	SendData(SendBUf, strlen(SendBUf));
	vTaskDelay(800);
	char *ret = strstr((char *)esp_buf, ">");
	memset(esp_buf, 0, 512);
	rxxcnt = 0;	
	if(ret != NULL)
	{
		SendData(cmd,len);//可能包含0x00 如果用strlen遇到0x00会停止
	} 

	

	vTaskDelay(2000);
	uint8_t rrrr = check_connect_ack();
	(rrrr == 1) ? (flag &= (~flagg)) : (flag |= flagg);//如果接收到了对应的内容，就不做如何置位，否则将对应位置一
	memset(esp_buf, 0, 512);//清空接收缓冲区
	rxxcnt = 0;//接收计数器清零	
	ret = NULL;
}

void ESP_Init_task(void *parameter)
{
	
	for(;;)
	{
		espcmd_init("AT\r\n", "OK", 0x01);
		while((flag & 0x01 == 0x01))
		{
			espcmd_init("AT\r\n", "OK", 0x01);
		}

		espcmd_init("AT+CWMODE=1\r\n", "OK", 0x02);
		while((flag & 0x02) == 0x02)
		{
			espcmd_init("AT+CWMODE=1\r\n", "OK", 0x02);
		}

		espcmd_init("AT+CWDHCP=1,1\r\n", "OK", 0x04);
		while((flag & 0x04) == 0x04)
		{
			espcmd_init("AT+CWDHCP=1,1\r\n", "OK", 0x04);
		}
	
		espcmd_init(ESP8266_WIFI_INFO, "WIFI GOT IP", 0x08);
		while((flag & 0x08) == 0x08)
		{
			espcmd_init(ESP8266_WIFI_INFO, "WIFI GOT IP", 0x08);
			vTaskDelay(200);		
		}
		//wifi已经连接好了
		xEventGroupSetBits(WIFI_connected_Handle, 1 << 4);

		espcmd_init(esp_tim, "OK",0x40);
		while((flag & 0x40) == 0x40)
		{
			espcmd_init(esp_tim, "OK",0x40);
		}

		espcmd_time_get("AT+CIPSNTPTIME?\r\n", "OK", 0x80);
		while((flag & 0x80) == 0x80)
		{
			espcmd_time_get("AT+CIPSNTPTIME?\r\n", "OK", 0x80);
		}

		
		// vTaskDelay(200);
		// espcmd_init("AT+CIPCLOSE", "OK", 0x01);
		// vTaskDelay(200);

		xEventGroupSetBits(TimeRefresh_Handle, 1 << 0);
		espcmd_init(ESP8266_TCP_INFO, "CONNECT", 0x10);
		while((flag & 0x10) == 0x10)
		{
			espcmd_init(ESP8266_TCP_INFO, "CONNECT", 0x10);
		}


		//连接mqtt的,发送mqtt的连接报文
		mqtt_espcmd_init((char *)mqtt_Connect_pack, 157, 0x20);
		while((flag & 0x20) == 0x20)
		{
			espcmd_init(ESP8266_TCP_INFO, "CONNECT", 0x10);
			while((flag & 0x10) == 0x10)
			{
				espcmd_init(ESP8266_TCP_INFO, "CONNECT", 0x10);
			}
			mqtt_espcmd_init((char *)mqtt_Connect_pack, 157, 0x20);
		}		
		
		xEventGroupSetBits(ESP_EventGroup_Handle, 1 << 2);//ESP32初始化结束之后，把对应的位置一，实现只有初始化结束之后才可以
		vTaskDelete(NULL);								//通过esp32来发送数据，初始化完成之后这任务会删除，只运行一次
	}
}
//查询是否断开连接mqtt，断开的话就自己连接
//每过一段时间就检查是否有连接上，可以在time中设置有个定时一秒的函数
//发送检查的时候需要将publish报文不发送，可以设置一个标志位，在time里面设置
//每到一段时间就发送标志位，关闭发送报文，或则将publish的任务挂起，在下面这个函数里面
//检测到标志位就开始检测，等检测好了重新置位标志开启publish报文
void re_checkconnect_mqtt(void)
{
//AT+CIPSTATUS
//设置标志位
	espcmd_init("AT+CIPSTATUS", "OK", 0x10);
	//如果没有被置位的话就不运行下面这段代码，直接开启publish报文发送数据
	if((flag & 0x10) == 0x10)//如果被置位了就代表断开了和TCP的连接   类似登录界面，实现一个界面
	{
		while((flag & 0x10) == 0x10)
		{
			espcmd_init(ESP8266_TCP_INFO, "CONNECT", 0x10);
		}

		mqtt_espcmd_init((char *)mqtt_Connect_pack, 157, 0x20);
		while((flag & 0x20) == 0x20)
		{
			espcmd_init(ESP8266_TCP_INFO, "CONNECT", 0x10);
			while((flag & 0x10) == 0x10)
			{
				espcmd_init(ESP8266_TCP_INFO, "CONNECT", 0x10);
			}
			mqtt_espcmd_init((char *)mqtt_Connect_pack, 157, 0x20);
		}

	}

	vTaskResume(espsend_Handle);
}
void ESP_SendData(char *ddata, uint8_t len)
{
	char SendBUf[128];
	sprintf(SendBUf, "AT+CIPSEND=%d\r\n", len);
	SendData(SendBUf, strlen(SendBUf));
	vTaskDelay(800);
	char *ret = strstr((char *)esp_buf, ">");
	if(ret != NULL)
	{
		SendData(ddata, len);
	}
	memset(esp_buf, 0, 512);
	rxxcnt = 0;
}


void ESP_SendNumm(uint8_t num)
{
	char SendBUf[128],buf[128];
	uint8_t length = sprintf(buf, "%d", num);
	sprintf(SendBUf, "AT+CIPSEND=%d\r\n", length);
	SendData(SendBUf, strlen(SendBUf));
	vTaskDelay(800);
	char *ret = strstr((char *)esp_buf, ">");
	if(ret != NULL)
	{
		SendData(buf, length);
	}
	memset(esp_buf, 0, 512);
	rxxcnt = 0;
}
void DATA_Join_Send(uint8_t num)
{
	char val_str[32];
	char last_buf[256]; 
	char one[32];
	char two[64];
	sprintf(one, "%.2f", bmp_gettemp());
	sprintf(two, "temp: %s", one);

	sprintf(val_str, "%d", num);
	sprintf(last_buf, "Light:%s  %s  press:%.4f", val_str, two, bmp_getPress());

	

	ESP_SendData(last_buf, strlen(last_buf));
}
void ESP_SendTask(void *parameter)
{
	for(;;)
	{
		EventBits_t uxBits = xEventGroupGetBits(ESP_EventGroup_Handle);
		if((uxBits & (1 << 2)) == (1 << 2))
		{
			// ESP_SendData("nihao",strlen("nihao"));
			// vTaskDelay(500);
			// ESP_SendNumm(cal_value);
			//DATA_Join_Send(cal_value);
			OnetNet_Post();
		}
		vTaskDelay(50);
	}
}
void USART0_IRQHandler(void)
{
	if(usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE) == SET)
	{		
		if(rxxcnt >= sizeof(esp_buf)) rxxcnt = 0;
		esp_buf[rxxcnt++] = usart_data_receive(USART0);		
		usart_interrupt_flag_clear(USART0, USART_INT_FLAG_RBNE);		
	}
}